Implement "compression" option in the TIFF pixbuf loader
authorChristian Dywan <christian@twotoasts.de>
Mon, 30 Nov 2009 12:55:12 +0000 (13:55 +0100)
committerChristian Dywan <christian@twotoasts.de>
Mon, 30 Nov 2009 12:55:12 +0000 (13:55 +0100)
This enables applications to read out the compression of a TIFF image
and also makes it possible to apply the same or a different
compression when saving.

Fixes: https://bugzilla.gnome.org/show_bug.cgi?id=584700
gdk-pixbuf/gdk-pixbuf-io.c
gdk-pixbuf/io-tiff.c

index 56271e16e022201761a86ac24f0ef7954519c0e0..f8ce73d9ab6b8cccf3a86b395c6117d21eb3321e 100644 (file)
@@ -1902,6 +1902,10 @@ gdk_pixbuf_real_save_to_callback (GdkPixbuf         *pixbuf,
  * be specified using the "compression" parameter; it's value is in an
  * integer in the range of [0,9].
  *
+ * TIFF images recognize a "compression" option which acceps an integer value.
+ * Among the codecs are 1 None, 2 Huffman, 5 LZW, 7 JPEG and 8 Deflate, see
+ * the libtiff documentation and tiff.h for all supported codec values.
+ *
  * ICO images can be saved in depth 16, 24, or 32, by using the "depth"
  * parameter. When the ICO saver is given "x_hot" and "y_hot" parameters,
  * it produces a CUR instead of an ICO.
index 2f62f38d603b4c7f0b67dd2b879699b589bd45df..7f8b79318e7dcad7c09c9b03ae17e709afce5948 100644 (file)
@@ -149,6 +149,7 @@ tiff_image_parse (TIFF *tiff, TiffContext *context, GError **error)
        GdkPixbuf *pixbuf;
        uint16 orientation = 0;
        uint16 transform = 0;
+        uint16 codec;
 
         /* We're called with the lock held. */
         
@@ -266,6 +267,13 @@ tiff_image_parse (TIFF *tiff, TiffContext *context, GError **error)
                gdk_pixbuf_set_option (pixbuf, "orientation", str);
        }
 
+        TIFFGetField (tiff, TIFFTAG_COMPRESSION, &codec);
+        if (codec > 0) {
+          gchar str[5];
+          g_snprintf (str, sizeof (str), "%d", codec);
+          gdk_pixbuf_set_option (pixbuf, "compression", str);
+        }
+
        if (context && context->prepare_func)
                (* context->prepare_func) (pixbuf, NULL, context->user_data);
 
@@ -689,6 +697,31 @@ gdk_pixbuf__tiff_image_save_to_callback (GdkPixbufSaveFunc   save_func,
         TIFFSetField (tiff, TIFFTAG_SAMPLESPERPIXEL, has_alpha ? 4 : 3);
         TIFFSetField (tiff, TIFFTAG_ROWSPERSTRIP, height);
 
+        /* libtiff supports a number of 'codecs' such as:
+           1 None, 2 Huffman, 5 LZW, 7 JPEG, 8 Deflate, see tiff.h */
+        if (keys && *keys && values && *values) {
+            guint i = 0;
+
+            while (keys[i]) {
+                if (g_str_equal (keys[i], "compression")) {
+                    guint16 codec = strtol (values[i], NULL, 0);
+                    if (TIFFIsCODECConfigured (codec))
+                        TIFFSetField (tiff, TIFFTAG_COMPRESSION, codec);
+                    else {
+                        tiff_set_error (error,
+                                        GDK_PIXBUF_ERROR_FAILED,
+                            _("TIFF compression doesn't refer to a valid codec."));
+
+                        tiff_pop_handlers ();
+
+                        free_save_context (context);
+                        return FALSE;
+                    }
+                }
+                i++;
+            }
+        }
+
         if (has_alpha)
                 TIFFSetField (tiff, TIFFTAG_EXTRASAMPLES, 1, alpha_samples);